/*******************************************************************************
 * Copyright (c) 2008 Nels E. Beckman.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Nels E. Beckman - initial API and implementation
 *******************************************************************************/
package edu.cmu.cs.nbeckman.wptranslator;

import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;

import antlr.RecognitionException;
import antlr.TokenStreamException;
import edu.cmu.cs.nbeckman.wptranslator.parser.WPDataLexer;
import edu.cmu.cs.nbeckman.wptranslator.parser.WPDataParser;

/**
 * The Document is the primary, in-memory representation of a word processing
 * document. One will be created when a WordPerfect document is read from a
 * file, and the data contained within a document will be used to print out
 * the content to another format.
 * 
 * @author Nels E. Beckman
 *
 */
public class Document {

	public enum OutputFormat {
		HTML {
			@Override
			public String getDescription() {
				return "Can be opened with web browser.";
			}
		}, RTF {
			@Override
			public String getDescription() {
				return "Can be opened by any word procecessor.";
			}
		};

		public static OutputFormat defaultFormat() {
			return HTML;
		}
		
		public abstract String getDescription();
	}
	
	private Element documentElements;

	public Document(Element elements) {
		this.documentElements = elements;
	}

	/**
	 * Primarily for testing.
	 */
	Element getElement() {
		return this.documentElements;
	}
	
	/**
	 * Given a WordPerfect file, create a Document.
	 * @throws IOException 
	 * @throws TokenStreamException 
	 * @throws RecognitionException 
	 */
	public static Document createDocumentFromFile(File file) throws IOException, RecognitionException, TokenStreamException {
		DataInputStream data_stream = null;
		try {
			data_stream = new DataInputStream(new FileInputStream(file));
			final WPDataLexer lexer = new WPDataLexer(data_stream);
			final WPDataParser parser = new WPDataParser(lexer);
			return parser.first();
		} finally {
			if( data_stream != null ) 
				data_stream.close();
		}
	}
	
	/**
	 * Write this document to the given file in the given file format.
	 * @throws FileNotFoundException 
	 */
	public void writeDocument(File file, OutputFormat outputFormat) throws FileNotFoundException {
		switch(outputFormat) {
		case HTML:
			this.writeHTML(file);
			break;
		case RTF:
			this.writeRTF(file);
			break;
		}
	}
	
	/**
	 * Write this document as HTML to the given file.
	 * @param file
	 * @throws FileNotFoundException
	 */
	public void writeHTML(File file) throws FileNotFoundException {
		PrintWriter writer = null;
		try {
			writer = new PrintWriter(file);
			writer.append(this.drawAsHTML());
		} finally {
			writer.close();
		}
	}
	
	/**
	 * Write this document as RTF to the given file.
	 * @param file
	 * @throws FileNotFoundException
	 */
	public void writeRTF(File file) throws FileNotFoundException {
		PrintWriter writer = null;
		try {
			writer = new PrintWriter(file);
			writer.append(this.drawAsRTF());
		} finally {
			writer.close();
		}
	}
	
	/**
	 * Return a string representation of this document in RTF format.
	 */
	public String drawAsRTF() {
		StringBuffer buf = new StringBuffer("{");
		
		// RTF Version
		buf.append("\\rtf\\ansi");
		
		// Using Times Roman as font #0
		buf.append("{\\fonttbl{\\f0\\froman Times New Roman;}}");
		
		buf.append(documentElements.drawAsRTF());
		buf.append("}");
		
		return buf.toString(); 
	}
	
	/**
	 * Return a representation of this document as HTML.
	 */
	public String drawAsHTML() {
		StringBuffer buf = new StringBuffer("<HTML><BODY>");
		buf.append(documentElements.drawAsHTML());
		buf.append("</BODY></HTML>");
		
		return buf.toString();
	}
}
